﻿/*!
 * nhis jQuery plugin.
 *
 * fengxianwen@gmail.com.
 * 2009-6-11 15:54, 2009-6-20 10:39
 *
 * Depends: jquery.js 1.3.2+
 *
 */

(function ($) {

    // ex String
    String.prototype.htmlEncode = function () { return $('<span/>').text(this.toString()).html().replace(/'/g, '&#39;').replace(/"/g, '&quot;'); };

    var _now = +new Date;

    var maxzIndex = 33554431;

    function uuid() {
        return 'nhis' + ++_now;
    };

    function isString(s) {
        return typeof (s) === 'string';
    };

    function isNumber(n) {
        return typeof (n) === 'number' && !isNaN(n);
    };

    function isStrOrNum(p) {
        return isString(p) || isNumber(p);
    };

    $.CellWeb = {
        errors: {
            ini: '定位 CellWeb 失败',
            x0: '失败',
            x1: '文件不存在',
            x2: '文件操作错误',
            x3: '文件格式错误',
            x4: '密码错误',
            x5: '不能打开高版本文件',
            x6: '不能打开特定版本文件',
            x99: '不能下载文件',
            xpct: '模板文件路径不能包含百分号(%)'
        },
        error: ''
    };

    // ex jQuery
    $.extend({

        // open CellWeb
        OpenCell: function (cllUrl, pwd, success, err) {
            error = function (msg) {
                $.CellWeb.error = msg;
                $.isFunction(err) ? (err(msg)) : ($.nhisAlert(msg));
            };

            if (!top.regCell()) {
                error($.CellWeb.errors.ini);
                return;
            }

            var p = cllUrl, idx = cllUrl.lastIndexOf('/');
            (idx > 0 && (p = cllUrl.substring(0, idx)));

            if (p.indexOf('%') >= 0) {
                error($.CellWeb.errors.xpct);
                return;
            }

            try {
                var rt = top._cellweb.openFile(encodeURI(cllUrl), pwd);

                if (rt < 1) {
                    error($.CellWeb.errors['x' + -rt]);
                    return;
                }

                ($.isFunction(success) && success(top._cellweb));
            } catch (e) {
                error(e);
            }
        },

        // overlay
        nhisOverlay: function (options) {

            OverlayBase.topOver =
        typeof options == 'undefined' ||
        (typeof options == 'boolean' && options) ||
        typeof options.topOver != 'boolean' ||
        options.topOver;

            return new OverlayDiv(options);
        },

        // loading
        nhisLoading: function (options) {

            return $.nhisOverlay($.extend({}, options, {
                speed: 0,
                opacity: 0,
                width: '128px',
                height: '15px',
                html: '<div class=nhisloader></div>'
            }));

        },

        // alert
        nhisAlert: function (msg) {
            if (typeof (_fengdonotified) == 'undefined' || !_fengdonotified) alert(msg);
            return;

            // todo suspend

            (isStrOrNum(msg) && (msg = msg.toString()) || (msg = ''));

            var oid = uuid(),
            o = '<table style="border-width:5px;border-color:#c5c5c5;width:300px;" cellpadding=0 cellspacing=0><tr><td style="text-align:center;background:#ffffff;padding:10px;">' + msg.htmlEncode() +
      '</td></tr><tr><td style="height:1px;background:silver"></td></tr><tr><td style="text-align:center;background:#ffffff;padding:10px;"><input ' + oid + '="1" type=button value=" 确定 " /></td></tr></table>';

            var ok = false;
            var rt = $.nhisOverlay({
                speed: 0,
                width: 'auto',
                height: 'auto',
                complete: function (fore, back) {
                    fore.append(o);
                    $('[' + oid + ']', OverlayBase.overContext()).focus().click(function () { fore.remove(); back.remove(); ok = true; });
                }
            });

        }

    });

    // OverlayBase
    var OverlayBase = function (options) {

        this.settings = OverlayBase.parseSettings(options);

        init(this);

        function init(o) {

            var s = o.settings;
            o.id = s.id ? s.id : uuid();

            o.jq = $('table[' + o.id + '=1]', OverlayBase.overContext());
            if (o.jq.length < 1) o.jq = null;

            if (!o.jq) {
                o.jq = o.jq || $('<table style="border:0px;margin:0px;padding:0px;position:fixed;display:none;"><tbody><tr><td></td></tr></tbody></table>',
        OverlayBase.overContext()).attr(o.id, '1');

                $('body', OverlayBase.overContext()).append(o.jq);
            }

            var t = o.jq;
            t.css({
                width: s.width,
                height: s.height,
                background: s.background,
                left: s.left,
                top: s.top,
                overflow: s.overflow,
                'z-index': maxzIndex
            });

            if (isString(s.html)) t.children().children().children().html(s.html);

            if (isString(s.cssfile) && $('[css_' + o.id + ']', OverlayBase.overContext()).length < 1) {
                $('head', OverlayBase.overContext())
          .append($('<link type="text/css" rel="stylesheet" />')
            .attr('href', s.cssfile).attr('css_' + o.id, '1'));
            }

            $(window, OverlayBase.overContext()).resize(function () { o.fix(); });

            t.fadeTo(0, 0, function () {
                t.show();
                t.fadeTo(s.speed, s.opacity, function () {
                    //t.focus();
                    if ($.isFunction(s.complete)) {
                        s.complete(o);
                    }
                    o.fix();
                });
            });

        };

    };

    // OverlayBase.topWidth, OverlayBase.topHeight
    $.each(['Width', 'Height'], function (i, n) {

        OverlayBase['top' + n] = function () {
            var c = OverlayBase.overContext();
            return c.compatMode == "CSS1Compat"
        && c.documentElement["client" + n]
			  || c.body["client" + n];
        };

    });

    // ex OverlayBase
    $.extend(OverlayBase, {

        defaults: {
            background: 'Silver',
            speed: 200,
            opacity: .5,
            width: '100%',
            height: '100%',
            left: 'auto',
            top: 'auto',
            overflow: 'auto',
            html: '',
            complete: function () { }
        },

        topOver: true,

        overContext: function () {
            return OverlayBase.topOver && window.top.document || window.document;
        },

        parseSettings: function (options) {

            return $.extend(
        {},
        OverlayBase.defaults,
        options === undefined ? {} : $.isFunction(options) ? ({ complete: options }) : ($.each(options, function (n, v) {

            if (!isString(n)) return false;
            n = n.toLowerCase();

            if (isString(v)) v = $.trim(v);
            else if (n != 'complete' && $.isFunction(v)) v = v.call();

            if (!isStrOrNum(v) && !$.isFunction(v)) v = undefined;

            options[n] = v;

        }), options)
      );

        },

        prototype: {

            // remove overlay
            remove: function (speed, callback) {

                if (!speed) speed = 0;

                if ($.isFunction(speed)) {
                    callback = speed;
                    speed = 0;
                }

                //if (this.jq) this.jq.hide();

                var o = this;

                if (!o.jq) return;

                var t = o.jq;
                if (t.length > 0) {
                    t.fadeTo(speed, 0, function () {
                        //t.blur();
                        //t.remove();
                        t.hide();

                        //o.jq = $('[' + o.id + ']', OverlayBase.overContext());
                        if ($.isFunction(callback)) callback();
                    });
                }
            },

            // postion, size
            fix: function () {

                var s = this.settings,
           ss = $.extend({}, s),
            d = OverlayBase.defaults,
            t = this.jq,
         maxh = OverlayBase.topHeight(),
         maxw = OverlayBase.topWidth();

                // fix percent
                $.each({ width: maxw, height: maxh, left: maxw, top: maxh }, function (name, max) {
                    var n = s[name].toString();
                    if (n.substr(n.length - 1) == '%') {
                        var p = new Number(n.substring(0, n.length - 1));
                        p = p > 100 ? 100 : p < 0 ? 0 : p;
                        ss[name] = max * p / 100 + 'px';
                    }
                });

                // fix auto
                $.each({
                    left: { n: 'width', m: maxw },
                    top: { n: 'height', m: maxh }
                }, function (n, oo) {
                    if (s[n] == 'auto') {
                        var l = oo.m - (ss[oo.n] == 'auto' ? t[oo.n]() : parseFloat(ss[oo.n]));
                        ss[n] = (l < 0 ? 0 : l) / 2 + 'px';
                    }
                });

                t.css({
                    'left': ss.left,
                    'top': ss.top,
                    'width': ss.width,
                    'height': ss.height
                });

                return this;

            }

        }

    });

    // OverlayDiv
    var OverlayDiv = function (options) {

        var s = OverlayBase.parseSettings(options), o = this,
       ss = $.extend({}, s, {
           background: 'transparent',
           id: '_OverlayDiv_fore',
           opacity: 1
       }), c = ss.complete;

        o.back = new OverlayBase({
            speed: s.speed,
            background: s.background,
            id: '_OverlayDiv_back',
            opacity: s.opacity
        });

        /*
        try {
        o.back.activeElement = !!document.activeElement && document.activeElement || null;
        if (o.back.activeElement) o.back.jq.focus();
        } catch (ex) { }
        */

        if ($.isFunction(c)) {
            ss.complete = function (f) {
                c(f, o.back);
            };
        }

        o.fore = new OverlayBase(ss);

    };

    // ex OverlayDiv
    $.extend(OverlayDiv, {
        prototype: {
            remove: function (speed, callback) {
                if (this.fore) this.fore.remove(speed, callback);
                //if (this.back.activeElement) { try { this.back.activeElement.focus(); } catch (ex) { } }
                if (this.back) this.back.remove(speed, callback);
                if (this.fore) delete this.fore;
                if (this.back) delete this.back;
            },
            fix: function () {
                this.fore.fix();
            }
        }
    });

    // add fn
    $.each($.fn, function (n, v) {
        if ($.isFunction(v) && !OverlayBase.prototype[n]) {

            OverlayBase.prototype[n] = function () {
                if (this.jq) {
                    return v.apply(this.jq.find('td'), arguments);
                }
                return this;
            };

            OverlayDiv.prototype[n] = function () {
                if (this.fore && this.fore.jq) {
                    return v.apply(this.fore.jq.find('td'), arguments);
                }
                return this;
            };

        }
    });

    var _maskO;
    $(document).ajaxStart(function () {
        _maskO = $.nhisLoading();
    }).ajaxStop(function () {
        if (_maskO) _maskO.remove();
    });

})(jQuery);

